/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Source.java
 *
 * Created on 23.11.2009, 18:10:34 
 */
package GUI.iFrames;

import input.IoToolbox;
import input.JxlExporter;

import java.awt.Component;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import org.jfree.data.xy.DefaultXYZDataset;

import toolz.JTableCustomizer;
import DATA.iDataSetParts.Measurement;
import GUI.BaseFrame;
import GUI.WaitJDialogModal;

/**
 * 
 * @author Bunkowski
 */
public class GeneralTabInternalFrame extends javax.swing.JInternalFrame implements DropTargetListener {

	public static final long serialVersionUID = 1L;

	public DropTarget dropTarget = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this, true, null);
	private Vector<Vector<String>> arrayData;
	private JTable table = new JTable();

	/** Creates new form Source */
	public GeneralTabInternalFrame() {
		initComponents();
		fitSize();
	}

	public GeneralTabInternalFrame(Vector<String[]> v) {
		initComponents();
		showTable(v);
		fitSize();
	}

	private void fitSize() {
		JTableCustomizer.fitAllColumnWidth(table);
		int columnSize = JTableCustomizer.getTotalColumnWidth(table);
		this.setSize(columnSize + 12, this.getHeight());
	}

	private void showTable(Vector<String[]> v) {
		arrayData = IoToolbox.transformVectorArrayToVectorVector(v);

		Vector<String> header = new Vector<String>();
		int maxSize = 0;
		for (int i = 0; i < v.size(); i++) {
			int stringsSize = v.elementAt(i).length;
			if (stringsSize > maxSize) {
				maxSize = stringsSize;
			}
		}
		for (int i = 0; i < maxSize; i++) {
			header.add(i + 1 + "");
		}

		table.setModel(new DefaultTableModel(arrayData, header));
		table.setDragEnabled(true);
		JScrollPane tableScrollpane = new JScrollPane(table);
		JTableCustomizer.changeComperatorToDoubleIfPossible(table);
		center.setLayout(new BoxLayout(center, BoxLayout.Y_AXIS));
		center.add(tableScrollpane);

		table.setColumnSelectionAllowed(true);
		table.setRowSelectionAllowed(true);

		trashLabel.table = table;
		dropTableHeader1.table = table;

		if (this.containsMeasurements() == false) {
			remove(infoLabel);
		}
	}

	private boolean containsMeasurements() {
		try {
			for (int i = 0; i < arrayData.size(); i++) {
				Vector<String> strings = arrayData.get(i);
				if (strings.get(0).endsWith("_ims.csv")) {
					return true;
				}
			}
		} catch (Exception ex) {
			return false;
		}
		return false;
	}

	private void matchDroppedMeasurementsWithLine0(Vector<Measurement> droppedMeasurements) {
		System.out.println("Data drop detected, trying to match ID or MI");

		Vector<Measurement> measurementsWithMatchingMeasurementID = new Vector<Measurement>();
		Vector<Measurement> measurementsWithMatchingPatientID = new Vector<Measurement>();
		Vector<String> missingFiles = new Vector<String>();

		Vector<String> column0 = new Vector<String>();
		for (int i = 0; i < arrayData.size(); i++) {
			Vector<String> strings = arrayData.get(i);
			column0.add(strings.get(0));
		}

		for (Measurement droppedMeasurement : droppedMeasurements) {
			if (column0.contains(droppedMeasurement.filename)) {
				measurementsWithMatchingMeasurementID.add(droppedMeasurement);
			}
			if (column0.contains(droppedMeasurement.patientID)) {
				measurementsWithMatchingPatientID.add(droppedMeasurement);
			}
		}

		// find missing files
		for (int j = 0; j < column0.size(); j++) {
			boolean fileFound = false;
			for (int i = 0; i < measurementsWithMatchingMeasurementID.size(); i++) {
				Measurement measurement = measurementsWithMatchingMeasurementID.elementAt(i);
				if (column0.get(j).equals(measurement.filename)) {
					fileFound = true;
				}
			}
			if (!fileFound) {
				missingFiles.add(column0.get(j));
			}
		}

		// transform missing file list to gtif format
		Vector<String[]> missingFilesArray = new Vector<String[]>();
		for (int i = 0; i < missingFiles.size(); i++) {
			String string = missingFiles.elementAt(i);
			missingFilesArray.add(new String[] { string, "could not be found" });
		}

		// open gtif with missing files
		if (missingFilesArray.size() > 0) {
			GeneralTabInternalFrame gtif = new GeneralTabInternalFrame(missingFilesArray);
			gtif.setLocation(new Point(this.getLocation().x, this.getLocation().y));
			BaseFrame.applyFrame(gtif);
		}

		if (measurementsWithMatchingMeasurementID.size() > 0) {
			BaseFrame.openDataSourcesInternalFrame(measurementsWithMatchingMeasurementID, new Point(
					this.getLocation().x, this.getLocation().y));
		}

		if (measurementsWithMatchingPatientID.size() > 0) {
			BaseFrame.openDataSourcesInternalFrame(measurementsWithMatchingPatientID, new Point(this.getLocation().x,
					this.getLocation().y));
		}
		this.dispose();
	}

	private void addInformationFromDrop(final String unknownDropSequence) {

		final Component parent = this;
		final WaitJDialogModal wait = new WaitJDialogModal("Adding drop information ...", parent);

		Runnable runnable = new Runnable() {

			public void run() {

				boolean abort = false;
				Vector<Measurement> measurements = new Vector<Measurement>();

				// String[] unknownDropLines = unknownDropSequence.split("\t");

				Vector<File> allFiles = IoToolbox.decodeTabbedFileString(unknownDropSequence);
				Vector<String> duplicationTest = new Vector<String>();
				for (File f : allFiles) {
					abort = wait.step("processing " + f.getName());
					if (abort) {
						break;
					}
					if (f.toString().endsWith("_ims.csv")) {
						if (duplicationTest.contains(f.getName().toString())) {
							System.out.println(f.getName().toString() + " is not unique");
						} else {
							duplicationTest.add(f.getName().toString());
							measurements.add(new Measurement(f.getPath()));
						}
					}
				}

				// for (String line : unknownDropLines) {
				// File testIfFile = new File(line);
				// if (testIfFile.exists()) {
				// if (testIfFile.toString().endsWith("_ims.csv")) {
				// measurements.add(new Measurement(line));
				// }
				// }
				// }

				if (measurements.size() > 0) {
					matchDroppedMeasurementsWithLine0(measurements);
				} else if (unknownDropSequence.split("\n")[0].split("\t").length == arrayData.get(0).size()) {
					System.out.println("append to table drop detected");
					for (String line : unknownDropSequence.split("\n")) {
						Vector<String> temp = new Vector<String>();
						for (String element : line.split("\t")) {
							temp.add(element);
						}
						arrayData.add(temp);
					}
					((DefaultTableModel) table.getModel()).fireTableDataChanged();
					fitSize();
				}

				// Waitdialog end step
				wait.dispose();

			}
		};
		Thread thread = new Thread(runnable);
		wait.setThread(thread);
		thread.start();
	}

	/**
	 * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The
	 * content of this method is always regenerated by the Form Editor.
	 */
	private void initComponents() {

		center = new javax.swing.JPanel();
		trashLabel = new toolz.TrashLabel();
		infoLabel = new javax.swing.JLabel();
		dropTableHeader1 = new toolz.DropTableHeader();
		jMenuBar1 = new javax.swing.JMenuBar();
		fileMenu = new javax.swing.JMenu();
		exportXlsMenuItem = new javax.swing.JMenuItem();
		correlationMenuItem = new javax.swing.JMenuItem();

		setClosable(true);
		setIconifiable(true);
		setMaximizable(true);
		setResizable(true);
		setTitle("Table builder");

		center.setBackground(new java.awt.Color(255, 255, 255));

		infoLabel.setBackground(new java.awt.Color(255, 255, 255));
		infoLabel.setText("Drop IMS files/folder on this window to open a data source containing matching files.");
		infoLabel.setOpaque(true);

		dropTableHeader1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
		dropTableHeader1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

		fileMenu.setText("File");

		exportXlsMenuItem.setText("export .xls");
		exportXlsMenuItem.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				exportXlsMenuItemActionPerformed(evt);
			}
		});
		fileMenu.add(exportXlsMenuItem);

		correlationMenuItem.setText("show correlation plot");
		correlationMenuItem.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				correlationMenuItemActionPerformed(evt);
			}
		});
		fileMenu.add(correlationMenuItem);

		jMenuBar1.add(fileMenu);

		setJMenuBar(jMenuBar1);

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						javax.swing.GroupLayout.Alignment.TRAILING,
						layout.createSequentialGroup()
								.addContainerGap(531, Short.MAX_VALUE)
								.addComponent(trashLabel, javax.swing.GroupLayout.PREFERRED_SIZE,
										javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
								.addGap(0, 0, 0))
				.addComponent(infoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
				.addComponent(dropTableHeader1, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
				.addComponent(center, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE));
		layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
				javax.swing.GroupLayout.Alignment.TRAILING,
				layout.createSequentialGroup()
						.addComponent(infoLabel)
						.addGap(2, 2, 2)
						.addComponent(dropTableHeader1, javax.swing.GroupLayout.PREFERRED_SIZE,
								javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
						.addGap(2, 2, 2)
						.addComponent(center, javax.swing.GroupLayout.DEFAULT_SIZE, 167, Short.MAX_VALUE)
						.addGap(5, 5, 5)
						.addComponent(trashLabel, javax.swing.GroupLayout.PREFERRED_SIZE,
								javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)));

		pack();
	}// </editor-fold>//GEN-END:initComponents

	private void exportXlsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_exportXlsMenuItemActionPerformed
		JxlExporter.exportXLS(table);
	}// GEN-LAST:event_exportXlsMenuItemActionPerformed

	private void correlationMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_correlationMenuItemActionPerformed
	// try{
		String[] labels = new String[arrayData.get(0).size() - 1];
		int k = 0;
		for (String s : arrayData.get(0)) {
			if (!s.equals("")) {
				labels[k] = s;
				k++;
			}
		}
		int elements = (arrayData.size() - 1) * (arrayData.size() - 1);
		double[][] posCorrData = new double[3][elements];
		double[][] negCorrData = new double[3][elements];

		int dindx = 0;
		for (int i = 1; i < arrayData.size(); i++) {
			for (int j = 1; j < arrayData.size(); j++) {
				Double corr = Double.parseDouble(arrayData.get(i).get(j));
				if (corr >= 0) {
					posCorrData[0][dindx] = i - 1;
					posCorrData[1][dindx] = j - 1;
					posCorrData[2][dindx] = corr;
				} else {
					negCorrData[0][dindx] = i - 1;
					negCorrData[1][dindx] = j - 1;
					negCorrData[2][dindx] = corr * -1;
				}
				dindx++;
			}
		}

		DefaultXYZDataset imsdds = new DefaultXYZDataset();

		imsdds.addSeries("negativ correlated", negCorrData);
		imsdds.addSeries("positiv correlated", posCorrData);

		CorrelationBubblePlot cif = new CorrelationBubblePlot(imsdds, labels, null);
		cif.setBounds(0, 0, 600, 400);
		BaseFrame.applyFrame(cif);
		cif.moveToFront();

		//
		// }catch(Exception ex){
		//
		// }
	}// GEN-LAST:event_correlationMenuItemActionPerformed

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JPanel center;
	private javax.swing.JMenuItem correlationMenuItem;
	private toolz.DropTableHeader dropTableHeader1;
	private javax.swing.JMenuItem exportXlsMenuItem;
	private javax.swing.JMenu fileMenu;
	private javax.swing.JLabel infoLabel;
	private javax.swing.JMenuBar jMenuBar1;
	private toolz.TrashLabel trashLabel;

	// End of variables declaration//GEN-END:variables

	public void dragEnter(DropTargetDragEvent dtde) {
	}

	public void dragOver(DropTargetDragEvent dtde) {
	}

	public void dropActionChanged(DropTargetDragEvent dtde) {
	}

	public void dragExit(DropTargetEvent dte) {
	}

	public void drop(DropTargetDropEvent evt) {
		try {
			Transferable t = evt.getTransferable();
			String unknownDropSequence = (String) t.getTransferData(DataFlavor.stringFlavor);
			addInformationFromDrop(unknownDropSequence);
		} catch (UnsupportedFlavorException ex) {
		} catch (IOException ex) {
		}
	}
}
